import { defineAsyncComponent, type InjectionKey, shallowRef, watchEffect } from 'vue'
import type { PerspectiveCamera, Scene, WebGLRenderer } from 'three'

/**
 * @Title: index
 * @Author  dudalei
 * @Package
 * @Date  2025/5/9 21:23
 * @description: 高德地图结合threejs demo
 */
export const AmapThree = defineAsyncComponent(() => import('./index.vue'))
export const AmapAndThreeInjectKey = Symbol('AmapAndThree') as InjectionKey<AmapAndThree>

type fnType = () => void
type asyncFnType = () => Promise<void>

export class AmapAndThree {
  private _map = shallowRef<any>()
  private _aMap = shallowRef<any>()
  private _camera = shallowRef<PerspectiveCamera>()
  private _renderer = shallowRef<WebGLRenderer>()
  private _scene = shallowRef<Scene>()
  constructor() {}

  get map() {
    return this._map.value as any
  }
  set map(value) {
    this._map.value = value
  }
  get aMap() {
    return this._aMap.value as any
  }
  set aMap(value) {
    this._aMap.value = value
  }
  get camera() {
    return this._camera.value as PerspectiveCamera
  }
  set camera(value) {
    this._camera.value = value
  }
  get renderer() {
    return this._renderer.value as WebGLRenderer
  }
  set renderer(value) {
    this._renderer.value = value
  }
  get scene() {
    return this._scene.value as Scene
  }
  set scene(value) {
    this._scene.value = value
  }

  /**
   * 这个方法用来保证map、aMap、camera、renderer、scene都加载完成之后再执行fn
   * @param fn
   */
  setup(fn: (amapAndThree: AmapAndThree) => void) {
    if (!fn) {
      return
    }
    watchEffect(() => {
      const { camera, renderer, scene, map, aMap } = this
      if (!map || !aMap || !camera || !renderer || !scene) {
        return
      }
      fn(this)
    })
  }

  _renders: Array<fnType | asyncFnType> = []
  /**
   * 地图渲染每帧执行
   * @param fn
   */
  onRender = (fn: fnType | asyncFnType) => {
    if (fn) {
      this._renders.push(fn)
    }
  }
}
